package com.future;

import com.future.util.TreeNode;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Description: 297. 二叉树的序列化与反序列化
 * 图片 Solution_297.png
 *
 * @author weiruibai.vendor
 * Date: 2022/9/29 16:43
 */
public class Solution_297 {

    public static void main(String[] args) {
        Solution_297 solution_297 = new Solution_297();
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.right.left = new TreeNode(4);
        root.right.right = new TreeNode(5);
        String serial = solution_297.serialize(root);
        System.out.println(serial);
        TreeNode deserialize = solution_297.deserialize(serial);
        System.out.println("");
    }

    // Encodes a tree to a single string. 1 2 null null 3 4 null null 5 null null
    public String serialize(TreeNode root) {
        LinkedList<TreeNode> linkedList = new LinkedList<>();
        StringBuilder sb = new StringBuilder("");
        serializeNode(root, sb);
        return sb.toString();
    }

    private void serializeNode(TreeNode root, StringBuilder sb) {
        if (root == null) {
            sb.append(".null");
            return;
        }
        sb.append("." + root.val);
        serializeNode(root.left, sb);
        serializeNode(root.right, sb);

    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        List<String> list = Arrays.asList(data.split("\\."));
        list = list.stream().filter(o -> !o.equals("")).collect(Collectors.toList());
        LinkedList linked = new LinkedList(list);
        return deserializeNode(linked);
    }

    private TreeNode deserializeNode(LinkedList<String> list) {
        if (list.isEmpty()) {
            return null;
        }
        String val = list.poll();
        if (val.equals("null")) {
            return null;
        }
        TreeNode head = new TreeNode(Integer.valueOf(val));
        head.left = deserializeNode(list);
        head.right = deserializeNode(list);
        return head;
    }
}
